home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 / Ham Radio 2000.iso / ham2000 / misc / coil / coil.c next >
C/C++ Source or Header  |  1992-12-21  |  8KB  |  437 lines

  1. /* Main program for electrical self inductance of a coil.
  2.  *
  3.  * Program by Steve Moshier
  4.  * moshier@world.std.com
  5.  *
  6.  * Last rev: December, 1992
  7.  */
  8.  
  9. double floor(), sqrt(), exp(), log(), pow();
  10. double skin(), helsol(), nagaoka(), rsol(), squaresol();
  11.  
  12. /* 0 for centimeters, 1 for inches */
  13. #define INCHES 1
  14.  
  15. double diameter = 0.0;
  16. double length = 0.0;
  17. double dbundle = 0.0;
  18. double outer = 0.0;
  19. double frequency = 0.0;
  20. double N = 0.0;
  21. double gauge = 0.0;
  22. int geometry = 1;
  23.  
  24. #define PI 3.14159265358979323846
  25.  
  26. extern double MACHEP; /* = 2.2e-16; */
  27. extern double MAXNUM; /* = 1.7e38; */
  28.  
  29.  
  30. char str[40];
  31.  
  32. main()
  33. {
  34. double b, p, d, l, a, L, s;
  35.  
  36.  
  37. printf( "Steve Moshier's Inductance Calculator v0.0\n\n" );
  38.  
  39. #if INCHES
  40. printf( "Dimensions in inches\n" );
  41. #else
  42. printf( "Dimensions in centimeters\n" );
  43. #endif
  44.  
  45. loop:
  46.  
  47. printf( "\nGeometry of coil:\n1 Circular solenoidal current sheet" );
  48. printf( "\n2 Straight round wire" );
  49. printf( "\n3 N-turn circular loop\n4 Circular toroid, circular winding" );
  50. printf( "\n5 Multilayer square solenoid (low precision)" );
  51. printf( "\n6 Circular torus ring, rectangular winding" );
  52. printf( "\n7 Multilayer circular solenoid" );
  53. printf( "\n8 Single-layer circular solenoid of round wire" );
  54. printf( "\n9 Single-layer square solenoid" );
  55. printf( "\n10 Wire gauge calculation\n" );
  56. printf( " Choose geometry (%d) ? ", geometry );
  57. gets( str );
  58. sscanf( str, "%d", &geometry );
  59. printf( "%d\n", geometry );
  60.  
  61.  
  62. if( geometry < 0 )
  63.     exit(0);   /* graceful exit to monitor */
  64.  
  65. if( (geometry <= 0) || (geometry > 10) )
  66.     goto operror;
  67.  
  68. if( geometry == 10 )
  69.     {
  70.     wire();
  71.     goto loop;
  72.     }
  73.  
  74. /* Thick circular solenoid
  75.  */
  76. if( geometry == 7 )
  77.     {
  78.     getnum( "Average diameter", &diameter, 0 );
  79. getrad:
  80.     getnum( "Radial depth of winding", &dbundle, 0 );
  81.     if( dbundle > diameter )
  82.         {
  83.         printf( "Depth cannot exceed diameter. Try again.\n" );
  84.         goto getrad;
  85.         }
  86.     getnum( "Length of winding", &length, 0 );
  87.     getnum( "Total number of turns", &N, 1 );
  88. #if INCHES
  89.     d = 2.54 * diameter;
  90.     l = 2.54 * length;
  91.     a = 2.54 * dbundle;
  92. #else
  93.     d = diameter;
  94.     l = length;
  95.     a = dbundle;
  96. #endif
  97.     L = rsol( 0.5*d, l, a, N );
  98.     goto done;
  99.     }
  100.  
  101. /* Circular torus ring of rectangular cross section
  102.  * Ref: Skilling 1948
  103.  */
  104. if( geometry == 6 )
  105.     {
  106.     getnum( "Inner diameter of circular torus ring", &diameter, 1 );
  107.     getnum( "Radial width of winding cross section", &dbundle, 0 );
  108.     getnum( "Height of winding cross section", &length, 0 );
  109.     getnum( "Total number of turns", &N, 0 );
  110. #if INCHES
  111.     d = 2.54 * diameter;
  112.     l = 2.54 * length;
  113.     a = 2.54 * dbundle;
  114. #else
  115.     d = diameter;
  116.     l = length;
  117.     a = dbundle;
  118. #endif
  119.     d *= 0.5;
  120.     L = 2.0e-9 * N * N * l * log( 1.0 + a/d );
  121.     goto done;
  122.     }
  123.  
  124. /* Square coil, rectangular winding cross section (thickness, length).
  125.  * Ref: Grover 1922a, CRC handbook
  126.  */
  127. if( (geometry == 5) || (geometry == 9) )
  128.     {
  129.   getnum( "Side of square, to center of winding thickness", &diameter, 1 );
  130.     getnum( "Winding length", &length, 1 );
  131.     if( geometry == 5 )
  132.         {
  133.         getnum( "Winding thickness", &dbundle, 0 );
  134.         }
  135.     getnum( "Total number of turns", &N, 0 );
  136.  
  137. #if INCHES
  138.     d = 2.54 * diameter;
  139.     l = 2.54 * length;
  140.     a = 2.54 * dbundle;
  141. #else
  142.     d = diameter;
  143.     l = length;
  144.     a = dbundle;
  145. #endif
  146.  
  147.     if( geometry == 9 )
  148.         {
  149.         L = squaresol( d, l, N );
  150.         }
  151.     else
  152.         {
  153.         if( (a+l) == 0.0 )
  154.             goto operror;
  155.         s = d/(a+l);
  156.         L = 8.e-9 * d * N * N * (log(s) + 0.2235/s + 0.726 );
  157.         }
  158.     goto done;
  159.     }
  160.  
  161. /* Circular toroid
  162.  * Ref: CRC handbook
  163.  */
  164. if( geometry == 4 )
  165.     {
  166. torrad:
  167.     getnum( "Radius distance from center of torus to center of winding",
  168.         &diameter, 0 );
  169.     getnum( "Diameter of circular winding", &length, 0 );
  170.     if( length > 2.0*diameter )
  171.         {
  172.         printf( "Diameter cannot exceed toroid diameter. Try again.\n" );
  173.         goto torrad;
  174.         }
  175.     getnum( "Total number of turns", &N, 0 );
  176.  
  177. #if INCHES
  178.     d = 2.54 * diameter;
  179.     l = 2.54 * length;
  180. #else
  181.     d = diameter;
  182.     l = length;
  183. #endif
  184.  
  185.     L = 4.0e-9 * PI * N * N * (d - sqrt(d*d - 0.25*l*l));
  186.     goto done;
  187.     }
  188.  
  189.  
  190. /* Solenoid, loop, or straight wire
  191.  */
  192. if( geometry == 2 )
  193.     { /* straight wire */
  194.     diameter = 0.0;
  195.     }
  196. else
  197.     {
  198.     getnum( "Diameter of winding", &diameter, 0 );
  199.     }
  200.  
  201. if( geometry == 3 )
  202.     { /* circular loop */
  203.     length = 0.0;
  204.     }
  205. else
  206.     {
  207.     if( geometry == 2 )
  208.         getnum( "Length of wire", &length, 0 );
  209.     else
  210.         getnum( "Length of winding", &length, 0 );
  211.     }
  212.  
  213. if( (length == 0.0) && (diameter == 0.0) )
  214.     {
  215.     L = 0.0;
  216.     goto done;
  217.     }
  218.  
  219. if( geometry == 8 )
  220.     getnum( "Wire diameter", &dbundle, 1 );
  221.  
  222. #if INCHES
  223. d = 2.54 * diameter;
  224. l = 2.54 * length;
  225. a = 2.54 * dbundle;
  226. #else
  227. d = diameter;
  228. l = length;
  229. a = dbundle;
  230. #endif
  231.  
  232. if( d == 0.0 )
  233.     goto straight;
  234.  
  235. getnum( "Total number of turns", &N, 0 );
  236.  
  237. if( l == 0.0 )
  238.     goto circloop;
  239.  
  240. if( geometry == 1 )
  241.     L = nagaoka( 0.5*d, l, N );
  242. else
  243.     {
  244.     if( a*N > l )
  245.         {
  246.         printf( "Wire diameter too large.\n" );
  247.         goto operror;
  248.         }
  249.     L = helsol( 0.5*d, l, a, N );
  250.     }
  251. goto done;
  252.  
  253.  
  254.  
  255.  
  256.  
  257. /* Ref: CRC handbook; Snow 1952
  258.  */
  259. circloop:
  260.  
  261. printf( "Circular loop.\n" );
  262. getnum( "Please enter diameter of wire or bundle of wires", &dbundle, 1 );
  263.  
  264. #if INCHES
  265. a = 2.54 * dbundle;
  266. #else
  267. a = dbundle;
  268. #endif
  269.  
  270. p = d/a;
  271. /* For "natural" current distribution b = -1
  272.  * For uniform current distribution b = 0 (Litz wire)
  273.  */
  274. b = -1.0;
  275.  
  276. if( N <= 1.0 )
  277.     s = skin(a);
  278. else
  279.     s = 0.25;
  280.  
  281. if( a <= 0.0 )
  282.     L = MAXNUM;
  283. else
  284.     {
  285.     L = 2.e-9 * PI * N * N * d
  286.   * ( (1.0 + (2.0*b+1.0)/(8.0*p)) * log(8.0*p) - 2.0 + s
  287.   + (b-1.0)*(b-2.0/3.0)/(16.0*p*p));
  288.     }
  289. goto done;
  290.  
  291.  
  292.  
  293.  
  294.  
  295. /* Ref: CRC handbook
  296.  */
  297. straight:
  298.  
  299.  
  300. printf( "Straight piece of wire.\n" );
  301. getnum( "Please enter diameter of wire", &dbundle, 1 );
  302.  
  303. #if INCHES
  304. a = 2.54 * dbundle;
  305. #else
  306. a = dbundle;
  307. #endif
  308.  
  309. L = 2.0e-9 * ( log(4.0*l/a) - 1.0 + skin(a) + 0.5*a/l );
  310.  
  311.  
  312.  
  313. done:
  314.  
  315. printf( "The inductance = %.3e henrys.\n", L );
  316.  
  317. goto loop;
  318.  
  319.  
  320. operror:
  321. printf( "? operator error\n" );
  322. goto loop;
  323.  
  324. }
  325.  
  326.  
  327.  
  328.  
  329.  
  330. /* Skin effect correction.
  331.  * This is a close empirical approximation to a table
  332.  * found in the CRC handbook.
  333.  */
  334. double skin( d )
  335. double d; /* wire diameter */
  336. {
  337. double s;
  338.  
  339. getnum( "Frequency in Hz, for skin effect", &frequency, 0 );
  340. if( frequency <= 0.0 )
  341.     return( 0.25 );
  342.  
  343. s = 0.1071 * d * sqrt(frequency);
  344. if( s > 100.0 )
  345.     {
  346.     s = 7.088/s;
  347.     }
  348. else
  349.     {
  350.     s = 0.00546 * pow(s,5.0);
  351.     s = 0.25 * pow( 1.0+s, -0.2 );
  352.     }
  353. return(s);
  354. }
  355.  
  356.  
  357.  
  358. /* Subroutine to get value entered on keyboard
  359.  * Displays previous value and updates only if a new value is entered.
  360.  */
  361. getnum( s, pd, zflag )
  362. char *s;
  363. double *pd;
  364. int zflag;
  365. {
  366. double t;
  367.  
  368. gloop:
  369. printf( "%s (%.5lf) ? ", s, *pd );
  370. gets(str);
  371.  
  372. if( (str[0] == '\0') && (*pd <= 0.0) )
  373.     {
  374.     t = *pd;
  375.     goto tests;
  376.     }
  377.  
  378. if( str[0] != '\0' )
  379.     {
  380.     sscanf( str, "%lf", &t );
  381. tests:
  382.     if( zflag >= 0 )
  383.     {
  384.     if( t < 0.0 )
  385.         {
  386.         printf( " ? Negative value not allowed; try again.\n" );
  387.         goto gloop;
  388.         }
  389.     if( zflag )
  390.         {
  391.         if( t == 0.0 )
  392.             {
  393.             printf( " ? Zero value not allowed; try again.\n" );
  394.             goto gloop;
  395.             }
  396.         }
  397.     }
  398.     *pd = t;
  399.     }
  400. /* Verify the value that will be used */
  401. if( *pd > 1.0e4 )
  402.     printf( "%.5e\n", *pd );
  403. else
  404.     printf( "%.5lf\n", *pd );
  405. }
  406.  
  407.  
  408. wire()
  409. {
  410. double b, c, d;
  411.  
  412.  
  413. getnum( "American Wire Gauge (B&S) number", &gauge, -1 );
  414.  
  415. d = 0.32485 * exp( -0.11594 * gauge );
  416.  
  417. printf( "Wire diameter = %.3e inches.\n", d );
  418. d *= 2.54; /* convert to centimeters */
  419. getnum( "Coil length", &length, 0 );
  420. getnum( "Winding thickness", &dbundle, 0 );
  421. #if INCHES
  422. b = 2.54*length;
  423. c = 2.54*dbundle;
  424. #else
  425. b = length;
  426. c = dbundle;
  427. #endif
  428. N = 1.0;
  429. b = floor( b/d );
  430. if( b > 0.0 )
  431.     N = b;
  432. c = floor( c/d );
  433. if( c > 0.0 )
  434.     N *= c;
  435. printf( "%.0lf turns will fit in this space.\n", N );
  436. }
  437.